import 'package:uuid/uuid.dart';
import 'family_member.dart';

/// u5bb6u5eadu6a21u578b
class Family {
  /// u5bb6u5eadu552fu4e00u6807u8bc6
  final String id;
  /// u5bb6u5eadu540du79f0
  final String name;
  /// u5bb6u5eadu6210u5458u5217u8868
  final List<FamilyMember> members;
  /// u5bb6u5eadu521bu5efau65f6u95f4
  final DateTime createdAt;
  /// u5bb6u5eadu521bu5efau8005ID
  final String creatorId;
  /// u5bb6u5eadu9080u8bf7u7801uff08u7528u4e8eu9080u8bf7u65b0u6210u5458uff09
  final String inviteCode;

  /// u6784u9020u51fdu6570
  Family({
    required this.id,
    required this.name,
    required this.members,
    required this.createdAt,
    required this.creatorId,
    required this.inviteCode,
  });

  /// u521bu5efau65b0u5bb6u5ead
  factory Family.create({
    required String name,
    required FamilyMember creator,
  }) {
    final id = const Uuid().v4();
    final inviteCode = _generateInviteCode();
    
    return Family(
      id: id,
      name: name,
      members: [creator],
      createdAt: DateTime.now(),
      creatorId: creator.id,
      inviteCode: inviteCode,
    );
  }

  /// u4eceJSONu521bu5efau5bb6u5eadu5bf9u8c61
  factory Family.fromJson(Map<String, dynamic> json) {
    return Family(
      id: json['id'] as String,
      name: json['name'] as String,
      members: (json['members'] as List<dynamic>)
          .map((member) => FamilyMember.fromJson(member as Map<String, dynamic>))
          .toList(),
      createdAt: DateTime.parse(json['createdAt'] as String),
      creatorId: json['creatorId'] as String,
      inviteCode: json['inviteCode'] as String,
    );
  }

  /// u8f6cu6362u4e3aJSON
  Map<String, dynamic> toJson() {
    return {
      'id': id,
      'name': name,
      'members': members.map((member) => member.toJson()).toList(),
      'createdAt': createdAt.toIso8601String(),
      'creatorId': creatorId,
      'inviteCode': inviteCode,
    };
  }

  /// u521bu5efau5bb6u5eadu526fu672cu5e76u66f4u65b0u6307u5b9au5b57u6bb5
  Family copyWith({
    String? id,
    String? name,
    List<FamilyMember>? members,
    DateTime? createdAt,
    String? creatorId,
    String? inviteCode,
  }) {
    return Family(
      id: id ?? this.id,
      name: name ?? this.name,
      members: members ?? this.members,
      createdAt: createdAt ?? this.createdAt,
      creatorId: creatorId ?? this.creatorId,
      inviteCode: inviteCode ?? this.inviteCode,
    );
  }

  /// u6dfbu52a0u5bb6u5eadu6210u5458
  Family addMember(FamilyMember member) {
    // u68c0u67e5u6210u5458u662fu5426u5df2u5b58u5728
    if (members.any((m) => m.id == member.id)) {
      return this;
    }
    
    return copyWith(
      members: [...members, member],
    );
  }

  /// u79fbu9664u5bb6u5eadu6210u5458
  Family removeMember(String memberId) {
    // u4e0du80fdu79fbu9664u521bu5efau8005
    if (memberId == creatorId) {
      return this;
    }
    
    return copyWith(
      members: members.where((member) => member.id != memberId).toList(),
    );
  }

  /// u66f4u65b0u5bb6u5eadu6210u5458
  Family updateMember(FamilyMember updatedMember) {
    return copyWith(
      members: members.map((member) {
        if (member.id == updatedMember.id) {
          return updatedMember;
        }
        return member;
      }).toList(),
    );
  }

  /// u66f4u65b0u5bb6u5eadu6210u5458u5fc3u60c5
  Family updateMemberMood(String memberId, MoodStatus mood) {
    return copyWith(
      members: members.map((member) {
        if (member.id == memberId) {
          return member.copyWith(
            mood: mood,
            moodUpdatedAt: DateTime.now(),
          );
        }
        return member;
      }).toList(),
    );
  }

  /// u83b7u53d6u5f53u524du7528u6237
  FamilyMember? get currentUser {
    return members.firstWhere(
      (member) => member.isCurrentUser,
      orElse: () => members.first,
    );
  }

  /// u83b7u53d6u5bb6u5eadu521bu5efau8005
  FamilyMember get creator {
    return members.firstWhere(
      (member) => member.id == creatorId,
      orElse: () => members.first,
    );
  }

  /// u91cdu65b0u751fu6210u9080u8bf7u7801
  Family regenerateInviteCode() {
    return copyWith(
      inviteCode: _generateInviteCode(),
    );
  }

  /// u751fu6210u968fu673au9080u8bf7u7801
  static String _generateInviteCode() {
    const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
    final random = const Uuid().v4();
    String code = '';
    
    for (int i = 0; i < 8; i++) {
      final index = random.codeUnitAt(i % random.length) % chars.length;
      code += chars[index];
    }
    
    return code;
  }
}
